//
//  ViewController.m
//  GestITDemo
//
//  Created by Davide Spano on 10/09/12.
//  Copyright (c) 2012 Davide Spano. All rights reserved.
//

#import "ViewController.h"
#import "DrawingView.h"
#import "TouchEmitter.h"
#import "SimpleTmpExp.h"
#import "ComplexTmpExp.h"
#import "TouchContent.h"
#import "BinaryTmpExp.h"
#import "TouchToken.h"
#import "GestureListener.h"
#import "TouchPoint.h"
#import <math.h>

#define FACTOR 0.01

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    UIScrollView* view = (UIScrollView*) self.view;
    view.contentSize=CGSizeMake(1280,960);
    [arrow1 setHidden:YES];
    [arrow2 setHidden:YES];
    
    TouchEmitter* emitter = [[TouchEmitter alloc] initWithView:self.view];
    
    // declare a pan
    SimpleTmpExp* touchStart = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:Start :1]];
    SimpleTmpExp* touchMove = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:Move :1]];
    touchMove.iterative = true;
    SimpleTmpExp* touchEnd = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:End :1]];
    
    BinaryTmpExp* b1 = [[BinaryTmpExp alloc] initWithOperands:touchMove :touchEnd :Disabling];
    BinaryTmpExp* pan = [[BinaryTmpExp alloc] initWithOperands:touchStart :b1 :Enabling];
    //pan.iterative = true;
    
    // declare a pinch
    SimpleTmpExp* touchStart1 = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:Start :1]];
    SimpleTmpExp* touchStart2 = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:Start :2]];
    
    SimpleTmpExp* touchMove1 = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:Move :1]];
    SimpleTmpExp* touchMove2 = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:Move :2]];
    touchMove1.iterative = true;
    touchMove2.iterative = true;
    
    SimpleTmpExp* touchEnd1 = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:End :1]];
    SimpleTmpExp* touchEnd2 = [[SimpleTmpExp alloc] initWithContent:[[TouchContent alloc] initWithTypeId:End :2]];
    
    ComplexTmpExp* start = [[ComplexTmpExp alloc] init];
    start.tmpOperator = OrderIndependence;
    [start addOperand:touchStart1];
    [start addOperand:touchStart2];
    
    BinaryTmpExp* move = [[BinaryTmpExp alloc] initWithOperands:touchMove1 :touchMove2 :Parallel];
    
    ComplexTmpExp* end = [[ComplexTmpExp alloc] init];
    end.tmpOperator = OrderIndependence;
    [end addOperand:touchEnd1];
    [end addOperand:touchEnd2];
    
    BinaryTmpExp* b2 = [[BinaryTmpExp alloc] initWithOperands:move :end :Disabling];
    BinaryTmpExp* pinch = [[BinaryTmpExp alloc] initWithOperands:start :b2 :Enabling];
    
    // declare the whole gesture
    BinaryTmpExp* gesture = [[BinaryTmpExp alloc] initWithOperands:pan :pinch :Choice];
    
    
    // attach listerners to the pan blocks
    [touchStart addGestureListener:[[GestureListener alloc]
                                   initWithReceiverSelectors:self
                                   withCompletedSelector:@selector(panStart:::)]];
    
    [touchMove addGestureListener:[[GestureListener alloc]
                                   initWithReceiverSelectors:self
                                   withCompletedSelector:@selector(panMoved:::)]];
    
    
    [touchEnd addGestureListener:[[GestureListener alloc]
                                    initWithReceiverSelectors:self
                                    withCompletedSelector:@selector(panEnd:::)]];
    
    // attach listeners to pinch blocks
    
    [touchStart1 addGestureListener:[[GestureListener alloc]
                                    initWithReceiverSelectors:self
                                    withCompletedSelector:@selector(pinchStart1:::)]];
    
    [touchStart2 addGestureListener:[[GestureListener alloc]
                                     initWithReceiverSelectors:self
                                     withCompletedSelector:@selector(pinchStart2:::)]];
    
    
    [touchMove1 addGestureListener:[[GestureListener alloc]
                                    initWithReceiverSelectors:self
                                    withCompletedSelector:@selector(pinchMoved1:::)]];
    
    [touchMove2 addGestureListener:[[GestureListener alloc]
                                    initWithReceiverSelectors:self
                                    withCompletedSelector:@selector(pinchMoved2:::)]];
    
    [touchEnd1 addGestureListener:[[GestureListener alloc]
                                     initWithReceiverSelectors:self
                                     withCompletedSelector:@selector(pinchEnd1:::)]];
    [touchEnd2 addGestureListener:[[GestureListener alloc]
                                     initWithReceiverSelectors:self
                                     withCompletedSelector:@selector(pinchEnd2:::)]];
    
    gesture.iterative = true;
    [emitter setGestureDescription:gesture];
    [emitter startRecognition:[[TouchToken alloc] initWithTracking:Previous]];
    
    zoom = 1.0;
    width = imageView.frame.size.width;
    height = imageView.frame.size.height;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
}


- (void) panMoved:(TmpExp *)sender :(ExpEventArgs *)args :(Token *)token{
    // translate the image
    TouchToken* tc = (TouchToken*) token;
    TouchPoint* previous = [tc getPreviousPosition:1];
    TouchPoint* current = [tc getPosition:1];
    imageView.frame = CGRectMake(imageView.frame.origin.x + (current.x - previous.x),
                                 imageView.frame.origin.y + (current.y - previous.y),
                                 imageView.frame.size.width,
                                 imageView.frame.size.height);
    [self moveArrow:arrow1: previous :current];
    NSLog(@"panMoved");
    //imageView.frame = CGRectMake(imageView.frame.origin.x, imageView.frame.origin.y, 1280,960);
}

- (void) pinchMoved1:(TmpExp *)sender :(ExpEventArgs *)args :(Token *)token{
    TouchToken* tc = (TouchToken*) token;
    TouchPoint* previous = [tc getPreviousPosition:1];
    TouchPoint* current = [tc getPosition:1];
    [self moveArrow:arrow1: previous :current];
    [self zoom:tc];
    //NSLog(@"pinchMoved1");

}

- (void) pinchMoved2:(TmpExp *)sender :(ExpEventArgs *)args :(Token *)token{
    TouchToken* tc = (TouchToken*) token;
    TouchPoint* previous = [tc getPreviousPosition:2];
    TouchPoint* current = [tc getPosition:2];
    [self moveArrow:arrow2: previous :current];
    [self zoom:tc];
    //NSLog(@"pinchMoved2");
}

- (void) zoom:(TouchToken*) tc{
    double oldDist = [self getDistance:[tc getPreviousPosition:1] :[tc getPreviousPosition:2]];
    double currDist =[self getDistance:[tc getPosition:1] :[tc getPosition:2]];
    double scale;
    if(currDist > oldDist){
        scale = 0.02;
    }else {
        scale = - 0.02;
    }
    
    zoom = MAX(zoom + scale, FACTOR);
    imageView.frame = CGRectMake(imageView.frame.origin.x ,
                                 imageView.frame.origin.y ,
                                 width * zoom,
                                 height * zoom);

}

- (double) getDistance:(TouchPoint*)a :(TouchPoint*)b{
    return sqrt(pow(b.x - a.x, 2) + pow(b.y - a.y, 2));
}


- (void) moveArrow:(UIImageView*) arrow :(TouchPoint*) a: (TouchPoint*)b{
    
    
    double angle = atan2(a.y - b.y, a.x - b.x);
    CGAffineTransform rotation = CGAffineTransformMakeRotation(angle);
    CGAffineTransform move = CGAffineTransformMakeTranslation(b.x - 50,
                                                              b.y - 100);
    CGAffineTransform transform = CGAffineTransformConcat(rotation, move);
    arrow.transform = transform;

}

- (void) panStart:(TmpExp*) sender :(ExpEventArgs *) args :(Token *) token{
    TouchToken* tc = (TouchToken*) token;
    TouchPoint* previous = [tc getPreviousPosition:1];
    TouchPoint* current = [tc getPosition:1];
    [self moveArrow:arrow1:previous :current];
    [arrow1 setHidden:NO];
}

- (void) pinchStart1:(TmpExp*) sender :(ExpEventArgs *) args :(Token *) token{
    TouchToken* tc = (TouchToken*) token;
    TouchPoint* previous = [tc getPreviousPosition:1];
    TouchPoint* current = [tc getPosition:1];
    [self moveArrow:arrow1:previous :current];
    [arrow1 setHidden:NO];
    NSLog(@"pinchStart1");
}

- (void) pinchStart2:(TmpExp*) sender :(ExpEventArgs *) args :(Token *) token{
    TouchToken* tc = (TouchToken*) token;
    TouchPoint* previous = [tc getPreviousPosition:2];
    TouchPoint* current = [tc getPosition:2];
    [self moveArrow:arrow2:previous :current];
    [arrow2 setHidden:NO];
    NSLog(@"pinchStart2");
}



- (void) panEnd:(TmpExp*) sender :(ExpEventArgs *) args :(Token *) token{
    [arrow1 setHidden:YES];
   // NSLog(@"panEnd1");
}

- (void) pinchEnd1:(TmpExp*) sender :(ExpEventArgs *) args :(Token *) token{
    [arrow1 setHidden:YES];
   // NSLog(@"panEnd1");
}

- (void) pinchEnd2:(TmpExp*) sender :(ExpEventArgs *) args :(Token *) token{
    [arrow2 setHidden:YES];
    //NSLog(@"panEnd2");
}







@end
